package com.otitan.la.forest.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.otitan.la.forest.system.constant.DicEnum;
import com.otitan.la.forest.system.dto.OrganizationDTO;
import com.otitan.la.forest.system.entity.AreaEntity;
import com.otitan.la.forest.system.entity.OrganizationEntity;
import com.otitan.la.forest.system.entity.UserOrgEntity;
import com.otitan.la.forest.system.mapper.OrganizationMapper;
import com.otitan.la.forest.system.service.DicService;
import com.otitan.la.forest.system.service.OrganizationService;
import com.otitan.la.forest.system.service.UserOrgService;
import com.otitan.la.forest.system.vo.*;
import com.otitan.webapp.framework.basepro.exception.code.BaseResponseCode;
import com.otitan.webapp.framework.basepro.model.DataResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class OrganizationServiceImpl extends ServiceImpl<OrganizationMapper, OrganizationEntity> implements OrganizationService {

    @Autowired
    private DicService dicService;
    @Autowired
    private UserOrgService userOrgService;
    @Resource
    private OrganizationMapper organizationMapper;

    @Override
    public DataResult add(OrganizationEntity organization, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return DataResult.fail(bindingResult.getFieldError().getDefaultMessage());
        }

        //组织机构不能重复
        LambdaQueryWrapper<OrganizationEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(OrganizationEntity::getCode, organization.getCode());
        queryWrapper.eq(OrganizationEntity::getName, organization.getName());
        int count = this.count(queryWrapper);
        if (count > 0) {
            return DataResult.fail("该组织机构已存在");
        }
        boolean isSuccess = this.save(organization);
        return isSuccess ? DataResult.success() : DataResult.fail(BaseResponseCode.DATA_NOT_EXIST.getMsg());
    }

    @Transactional
    @Override
    public DataResult batchDelete(List<String> ids) {
        LambdaQueryWrapper<UserOrgEntity> userOrgWrapper = Wrappers.lambdaQuery();
        userOrgWrapper.in(UserOrgEntity::getOrgId,ids);
        int count=userOrgService.count(userOrgWrapper);
        if(count>0){
            return  DataResult.fail("该组织机构已关联用户，请先取消用户与该组织机构的关联或者删除用户");
        }
        LambdaQueryWrapper<OrganizationEntity> organizationWrapper = Wrappers.lambdaQuery();
       organizationWrapper.in(OrganizationEntity::getParentId,ids);
       int counts=organizationMapper.selectCount(organizationWrapper);
        if(counts>0){
            return DataResult.fail("该组织机构有下级组织机构，请先删除下级组织机构");
        }
        boolean isSuccess = this.removeByIds(ids);
        log.debug("\n>>>>>>>>> 【删除组织机构表】 <<<<<<<<<\n操作结果：{}，ids：{}\n>>>>>>>>> ---- <<<<<<<<<", isSuccess, ids);
        return isSuccess ? DataResult.success() : DataResult.fail(BaseResponseCode.DATA_NOT_EXIST.getMsg());
    }

    @Override
    public DataResult editor(OrganizationEntity organization, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return DataResult.fail(bindingResult.getFieldError().getDefaultMessage());
        }

        //组织机构不能重复
        LambdaQueryWrapper<OrganizationEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(OrganizationEntity::getCode, organization.getCode());
        queryWrapper.eq(OrganizationEntity::getName, organization.getName());
        queryWrapper.ne(OrganizationEntity::getId, organization.getId());
        int count = this.count(queryWrapper);
        if (count > 0) {
            return DataResult.fail("该组织机构已存在");
        }

        boolean isSuccess = this.updateById(organization);
        return isSuccess ? DataResult.success() : DataResult.fail(BaseResponseCode.DATA_NOT_EXIST.getMsg());
    }

    @Override
    public DataResult findPageData(long page, long size, OrganizationDTO organization) {
        Page pagePlug = new Page(page, size);
        LambdaQueryWrapper<OrganizationEntity> queryWrapper = Wrappers.lambdaQuery();
        IPage<OrganizationEntity> iPage = this.page(pagePlug, queryWrapper);
        IPage<OrganizationEntityVO> iPageVO=new Page<>();
        BeanUtils.copyProperties(iPage, iPageVO);

        List<OrganizationEntityVO> orgList=new ArrayList<>();
        if(CollUtil.isNotEmpty(iPage.getRecords())){
            iPage.getRecords().forEach(organizationVO->{
                OrganizationEntityVO vo=new OrganizationEntityVO();
                BeanUtils.copyProperties(organizationVO, vo);
                String statusName=dicService.getDicName(DicEnum.ORGANIZATION_TYPE.getValue(),organizationVO.getStatus());
                vo.setStatusName(statusName);
                orgList.add(vo);
            });
        }
        iPageVO.setRecords(orgList);
        return DataResult.success(iPage);
    }

    @Override
    public DataResult findOne(String id) {
        OrganizationEntity organizationEntity=this.getById(id);
        OrganizationEntityVO organizationEntityVO=new OrganizationEntityVO();
        BeanUtils.copyProperties(organizationEntity, organizationEntityVO);
        String statusName=dicService.getDicName(DicEnum.ORGANIZATION_TYPE.getValue(),organizationEntityVO.getStatus());
        organizationEntityVO.setStatusName(statusName);
        return DataResult.success(organizationEntityVO);
    }

    /**
     * 获取组织机构列表树
     *
     * @param
     * @return java.util.List<com.otitan.la.forest.system.vo.OrganizationTreeVO>
     * @throws
     * @author Sunke
     * @date 2020/9/21 0021 16:46
     */
    @Override
    public List<OrganizationTreeVO> getOrganizationTree() {
        List<OrganizationTreeVO> orgList = organizationMapper.findOrgTree();
        List<OrganizationTreeVO> orgTree=formatData(orgList,"0");
        return orgTree;
    }

     public List<OrganizationTreeVO> formatData(List<OrganizationTreeVO> orgList,String parentId){
            if(CollectionUtil.isNotEmpty(orgList)){
                List<OrganizationTreeVO> otv=new ArrayList<>();
                orgList.forEach(item -> {
                    if(parentId.equals(item.getParentId())){
                        otv.add(item);
                    }
                });
                for (OrganizationTreeVO orgVO : otv) {
                    getMenuTree(orgVO, orgList);
                }
                return otv;
            }
            return null;
        }

        /**
         * 递归创建组织树
         * @author Sunke
         * @param  org, orgList
         * @return void
         * @exception
         * @date 2020/9/22 0022 11:40
         */
        private void getMenuTree(OrganizationTreeVO org, List<OrganizationTreeVO> orgList) {
            boolean flag = true;
            for (OrganizationTreeVO orgVO : orgList) {
                if (org.getId().equals(orgVO.getParentId())) {
                    getMenuTree(orgVO, orgList);
                    org.getChildren().add(orgVO);
                    org.setLeaf(Boolean.FALSE);
                    flag = false;
                }
            }
            if (flag) {
                org.setLeaf(Boolean.TRUE);
            }
    }

    @Override
    public List<OrganizationStationVO> findOrgMap() {
        return organizationMapper.findOrgMap();
    }

    @Override
    public List<OrganizationEntity> findOrgInfoByUserId(String userId) {
        List<OrganizationEntity> orgInfo = baseMapper.findOrgInfoByUserId(userId);
        return orgInfo;
    }

    /**
     * @Description:    通过组织机构名查询地区编码和id
     * @Author:        wangqingsong
     * @exception          [orgName]
     * @return             com.otitan.webapp.framework.basepro.model.DataResult
     * @CreateDate:     2020/10/22 14:59
     */
    @Override
    public DataResult findCodeAndIdByOrg(String orgName) {
        LambdaQueryWrapper<OrganizationEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(OrganizationEntity::getName, orgName);
        OrganizationEntity organizationEntity = this.getOne(queryWrapper);
        return DataResult.success(organizationEntity);
    }

    /**
     * @Description:    通过id查询组织机构名
     * @Author:        wangqingsong
     * @exception          [id]
     * @return             com.otitan.webapp.framework.basepro.model.DataResult
     * @CreateDate:     2020/10/22 16:44
     */
    @Override
    public DataResult findOrgById(String id) {
        OrganizationEntity organizationEntity = this.getById(id);
        return DataResult.success(organizationEntity);
    }
}